package com.ht.modules.system.online.codegenerate.generate.impl.a;

import com.ht.modules.system.online.codegenerate.a.ConfigVo;
import com.ht.modules.system.online.codegenerate.generate.a.LoadTemplatesUtil;
import com.ht.modules.system.online.codegenerate.generate.util.NonceUtils;
import com.ht.modules.system.online.codegenerate.generate.util.SimpleFormat;
import com.ht.modules.system.online.codegenerate.generate.util.g;
import freemarker.cache.FileTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.core.TemplateClassResolver;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Slf4j
public class FileTemplate {
    protected static String ENCODING_FORMAT = "UTF-8";
    protected List<String> generateCodeResult = new ArrayList<>();

    public void getAllFiles(File directoryFiles, List<File> files) {
        if (directoryFiles.isFile()) {
            files.add(directoryFiles);
            return;
        }
        File[] listFiles = directoryFiles.listFiles();
        if (listFiles == null) {
            return;
        }
        for (File file : listFiles) {
            this.getAllFiles(file, files);
        }
    }

    protected void generateCodeFiles(LoadTemplatesUtil loadTemplatesUtil, String projectPath, Map<String, Object> codeGenerateInfo, ConfigVo configVo) {
        try {
            List<File> fileList = loadTemplatesUtil.loadTemplates();
            for (File file : fileList) {
                log.info("load template from templateRootDir = '{}',stylePath ='{}',  out GenerateRootDir:{}", file.getAbsolutePath(), loadTemplatesUtil.getStylePath(), projectPath);
                List<File> files = new ArrayList<>();
                this.getAllFiles(file, files);
                for (File f : files) {
                    String templatesPath = f.getAbsolutePath().substring(file.getAbsolutePath().length() + 1);
                    String var7 = a(codeGenerateInfo, templatesPath, loadTemplatesUtil);
                    String var8 = projectPath + File.separator + configVo.sourceRootPackage.replace(".", File.separator);
                    String filePath = var8 + File.separator + var7;
                    if (filePath.contains("\\")) {
                        filePath = filePath.replace("\\", File.separator);
                    }
                    this.codeGeneration(templatesPath, filePath, codeGenerateInfo, loadTemplatesUtil);
                }
            }
        } catch (Exception var10) {
            log.error(var10.toString(), var10);
        }
    }

    protected void codeGeneration(String templatesPath, String filePath, Map<String, Object> codeGenerateInfo, LoadTemplatesUtil loadTemplatesUtil) throws Exception {
        if (filePath.endsWith("i")) {
            filePath = filePath.substring(0, filePath.length() - 1);
        }
        if (filePath.contains("__") && !filePath.matches("V\\d{8}_\\d{1,2}__.*\\.sql")) {
            filePath = filePath.replace("__", ".");
        }
        String var6 = filePath;
        if (filePath.endsWith(".vue")) {
            var6 = filePath.substring(0, filePath.length() - 4);
        }
        if (!var6.contains("vue") || !Boolean.parseBoolean(g.c(loadTemplatesUtil.getVueStyle())) || filePath.contains(loadTemplatesUtil.getVueStyle() + File.separator)) {
            List<File> files = loadTemplatesUtil.loadTemplates();
            Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
            FileTemplateLoader[] fileTemplateLoaders = new FileTemplateLoader[files.size()];
            for (int i = 0; i < files.size(); ++i) {
                File file = files.get(i);
                fileTemplateLoaders[i] = new FileTemplateLoader(file);
            }
            MultiTemplateLoader multiTemplateLoader = new MultiTemplateLoader(fileTemplateLoaders);
            configuration.setTemplateLoader(multiTemplateLoader);
            configuration.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);
            configuration.setNumberFormat("###############");
            configuration.setBooleanFormat("true,false");
            configuration.setDefaultEncoding("UTF-8");
            File file = new File(filePath);
            if (file.getParentFile() != null) {
                boolean mkdirs = file.getParentFile().mkdirs();
                if (mkdirs) {
                    log.info("[create]\t create dir:{}", file.getParentFile().getAbsolutePath());
                }
            }
            log.info("[generate]\t template:{} ==> {}", templatesPath, filePath);
            codeGenerateInfo.put("Format", new SimpleFormat());
            codeGenerateInfo.put("currentDate", NonceUtils.now());
            BufferedWriter bufferedWriter = null;
            try {
                Template template = configuration.getTemplate(templatesPath);
                template.setOutputEncoding("UTF-8");
                bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
                template.process(codeGenerateInfo, bufferedWriter);
                bufferedWriter.close();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            } finally {
                if (bufferedWriter != null) {
                    bufferedWriter.close();
                }
            }
            if (file.getName().startsWith("[1-n]")) {
                this.codeGeneration(file);
            } else {
                this.generateCodeResult.add("生成成功：" + filePath);
            }
        }
    }

    protected void codeGeneration(File var1) {
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        List<OutputStreamWriter> outputStreamWriters = new ArrayList<>();
        try {
            inputStreamReader = new InputStreamReader(new FileInputStream(var1), StandardCharsets.UTF_8);
            bufferedReader = new BufferedReader(inputStreamReader);
            boolean var7 = false;
            OutputStreamWriter outputStreamWriter = null;
            String value;
            while ((value = bufferedReader.readLine()) != null) {
                if (!value.trim().isEmpty() && value.startsWith("#segment#")) {
                    String noSegment = value.substring("#segment#".length());
                    String var10 = var1.getParentFile().getAbsolutePath();
                    noSegment = var10 + File.separator + noSegment;
                    log.info("[generate]\t split file:{} ==> {}", var1.getAbsolutePath(), noSegment);
                    outputStreamWriter = new OutputStreamWriter(new FileOutputStream(noSegment), StandardCharsets.UTF_8);
                    outputStreamWriters.add(outputStreamWriter);
                    this.generateCodeResult.add("生成成功：" + noSegment);
                    var7 = true;
                } else if (var7) {
                    outputStreamWriter.append(value).append("\r\n");
                }
            }
            for (OutputStreamWriter out : outputStreamWriters) {
                out.close();
            }
            bufferedReader.close();
            inputStreamReader.close();
            boolean b = deleteFile(var1);
            if (b) {
                log.info("[delete]\t delete file:{}", var1.getAbsolutePath());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if (inputStreamReader != null) {
                    inputStreamReader.close();
                }
                if (!outputStreamWriters.isEmpty()) {
                    for (OutputStreamWriter outputStreamWriter : outputStreamWriters) {
                        if (outputStreamWriter != null) {
                            outputStreamWriter.close();
                        }
                    }
                }
            } catch (Exception ignored) {
            }
            throw new RuntimeException(e);
        }
    }

    protected static String a(Map<String, Object> codeGenerateInfo, String templatesPath, LoadTemplatesUtil var2) throws Exception {
        List<File> files = var2.loadTemplates();
        Configuration var12 = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        FileTemplateLoader[] var4 = new FileTemplateLoader[files.size()];
        for (int var5 = 0; var5 < files.size(); ++var5) {
            File var6 = files.get(var5);
            var4[var5] = new FileTemplateLoader(var6);
        }
        var12.setTemplateLoader(new MultiTemplateLoader(var4));
        var12.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);
        var12.setNumberFormat("###############");
        var12.setBooleanFormat("true,false");
        var12.setDefaultEncoding("UTF-8");
        StringWriter stringWriter = new StringWriter();
        Template template = new Template("templateString...", new StringReader(templatesPath), var12);
        template.process(codeGenerateInfo, stringWriter);
        String var3 = stringWriter.toString();
        String var13 = var2.getStylePath();
        if (var13 != null && !var13.isEmpty()) {
            var3 = var3.substring(var13.length() + 1);
        }
        var3 = var3.substring(0, var3.lastIndexOf(".")).replace(".", File.separator) + var3.substring(var3.lastIndexOf("."));
        return var3;
    }

    protected static boolean deleteFile(File file) {
        boolean flag = false;
        for (int i = 0; !flag && i++ < 10; flag = file.delete()) {
            System.gc();
        }
        return flag;
    }
}
